/**
 * @file w25q64.h
 * @author leijiapeng (email:leijiapeng123@163.com)
 * @brief   实际使用的是W25Q128，函数名字有歧义，注意辨别
 * @version 0.1
 * @date 2025-09-18
 *
 * @copyright Copyright (c) 2025
 *
 */

#ifndef __W25QXX_H
#define __W25QXX_H

#include "stdint.h"

#define W25QXX_ERASE_SECTOR_MASK 0xFFFFF000 // 擦除以扇区为单位，擦除的地址必须对齐到4096字节的倍数

// MID和DID是通过W25QXX_ReadID()读取到的
#define W25Q128_MID              0xef
#define W25Q128_DID              0x4018 // 40表示是W25Q128JV/Q/JW 系列，18表示128Mbit

#define W25Q128_BLOCK_SIZE       64 * 1024 // 每块大小，单位字节
#define W25Q128_BLOCK_COUNT      256       // 块数量

#define W25Q128_SECTOR_SIZE      4 * 1024                 // 每扇区大小，单位字节
#define W25Q128_SECTOR_COUNT     16 * W25Q128_BLOCK_COUNT // 扇区数量，一个块16个扇区

#define W25Q128_PAGE_SIZE        256                       // 每页大小，单位字节
#define W25Q128_PAGE_COUNT       16 * W25Q128_SECTOR_COUNT // 页数量，一个扇区16页

#define W25Q128_CAPACITY         W25Q128_BLOCK_SIZE *W25Q128_BLOCK_COUNT // 总容量，单位字节

typedef struct
{
    uint8_t  MID; // 厂商ID
    uint16_t DID; // 设备ID

    uint16_t PageSize;    // 每页大小，单位字节
    uint16_t PageCount;   // 页数量
    uint16_t SectorSize;  // 每扇区大小，单位字节
    uint16_t SectorCount; // 总扇区数
    uint32_t BlockSize;   // 每块大小，单位字节
    uint16_t BlockCount;  // 总块数
    uint32_t Capacity;    // 总容量，单位字节
} W25QXX_s;

void W25QXX_Init(void);
void W25QXX_ReadID(uint8_t *MID, uint16_t *DID);
void W25QXX_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count);
void W25QXX_SectorErase(uint32_t Address);
void W25QXX_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count);

uint32_t sector_to_address(uint32_t sector);
uint32_t page_to_address(uint32_t page);

#endif // !__W25QXX_H